﻿//-----------------------------------------------------------------------
// <copyright file="CommonExtensions.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Web.Routing;

    /// <summary>
    /// Common Extensions
    /// </summary>
    public static class CommonExtensions
    {
        /// <summary>
        /// Builds the query string.
        /// </summary>
        /// <param name="queryParameters">The query parameters.</param>
        /// <returns>Query String</returns>
        public static string BuildQueryString(this NameValueCollection queryParameters)
        {
            if (queryParameters == null)
            {
                return string.Empty;
            }

            List<string> list = new List<string>();
            foreach (string str in queryParameters.AllKeys)
            {
                foreach (string str2 in queryParameters.GetValues(str))
                {
                    list.Add(str + "=" + Uri.EscapeDataString(str2));
                }
            }

            return string.Join("&", list.ToArray());
        }

        /// <summary>
        /// Converts to local.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info.</param>
        /// <param name="dateTime">The date time.</param>
        /// <returns>Local Date Time</returns>
        public static DateTime ConvertToLocal(this TimeZoneInfo timeZoneInfo, DateTime dateTime)
        {
            return TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Utc, timeZoneInfo);
        }

        /// <summary>
        /// Converts to UTC.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info.</param>
        /// <param name="dateTime">The date time.</param>
        /// <returns>UTC Date Time</returns>
        public static DateTime ConvertToUtc(this TimeZoneInfo timeZoneInfo, DateTime dateTime)
        {
            return TimeZoneInfo.ConvertTime(dateTime, timeZoneInfo, TimeZoneInfo.Utc);
        }

        /// <summary>
        /// Formats the specified format.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <param name="args">The arguments.</param>
        /// <returns>Formatted string</returns>
        public static string Format(this string format, params object[] args)
        {
            return string.Format(CultureInfo.CurrentCulture, format, args);
        }

        /// <summary>
        /// Formats the current.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <param name="args">The arguments.</param>
        /// <returns>Formatted string</returns>
        public static string FormatCurrent(this string format, params object[] args)
        {
            return string.Format(CultureInfo.CurrentCulture, format, args);
        }

        /// <summary>
        /// Formats the invariant.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <param name="args">The arguments.</param>
        /// <returns>Formatted string</returns>
        public static string FormatInvariant(this string format, params object[] args)
        {
            return string.Format(CultureInfo.InvariantCulture, format, args);
        }

        /// <summary>
        /// Formats the UI.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <param name="args">All arguments.</param>
        /// <returns>Formatted string for UI</returns>
        public static string FormatUI(this string format, params object[] args)
        {
            return string.Format(CultureInfo.CurrentCulture, format, args);
        }

        /// <summary>
        /// Encodes HTML.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>Html Encoded string</returns>
        public static string HtmlEncode(this string value)
        {
            return Microsoft.Security.Application.Encoder.HtmlEncode(value);
        }

        /// <summary>
        /// Merges the specified dictionary.
        /// </summary>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="routeValues">The route values.</param>
        /// <returns>Merged Route Value Dictionary</returns>
        public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, object routeValues)
        {
            return dictionary.Merge(routeValues, true);
        }

        /// <summary>
        /// Merges the specified dictionary.
        /// </summary>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="routeValues">The route values.</param>
        /// <returns>Merged Route Value Dictionary</returns>
        public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, RouteValueDictionary routeValues)
        {
            return dictionary.Merge(routeValues, true);
        }

        /// <summary>
        /// Merges the specified dictionary.
        /// </summary>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="routeValues">The route values.</param>
        /// <param name="replaceExisting">if set to <c>true</c> [replace existing].</param>
        /// <returns>Merged Route Value Dictionary</returns>
        public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, object routeValues, bool replaceExisting)
        {
            if ((routeValues != null) && !(routeValues is RouteValueDictionary))
            {
                return dictionary.Merge(new RouteValueDictionary(routeValues), replaceExisting);
            }

            return dictionary.Merge((RouteValueDictionary)routeValues, replaceExisting);
        }

        /// <summary>
        /// Merges the specified dictionary.
        /// </summary>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="routeValues">The route values.</param>
        /// <param name="replaceExisting">if set to <c>true</c> [replace existing].</param>
        /// <returns>Merged Route Value Dictionary</returns>
        public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, RouteValueDictionary routeValues, bool replaceExisting)
        {
            if (routeValues != null)
            {
                foreach (KeyValuePair<string, object> pair in routeValues)
                {
                    if (replaceExisting || !dictionary.ContainsKey(pair.Key))
                    {
                        dictionary[pair.Key] = pair.Value;
                    }
                }
            }

            return dictionary;
        }

        /// <summary>
        /// To the browser safe string.
        /// </summary>
        /// <param name="uri">The URI.</param>
        /// <returns>string URI for safe browsing</returns>
        public static string ToBrowserSafeString(this Uri uri)
        {
            if (uri == null)
            {
                return string.Empty;
            }

            if (uri.IsUnc)
            {
                return "file://///" + uri.Authority + uri.PathAndQuery;
            }

            if (uri.IsFile)
            {
                return "file:///" + uri.Authority + uri.PathAndQuery;
            }

            return uri.ToString();
        }

        /// <summary>
        /// To the URI.
        /// </summary>
        /// <param name="uriString">The URI string.</param>
        /// <returns>Uri object</returns>
        public static Uri ToUri(this string uriString)
        {
            return uriString.ToUri(UriKind.RelativeOrAbsolute);
        }

        /// <summary>
        /// To the URI.
        /// </summary>
        /// <param name="uriString">The URI string.</param>
        /// <param name="uriKind">Kind of the URI.</param>
        /// <returns>Uri object</returns>
        public static Uri ToUri(this string uriString, UriKind uriKind)
        {
            Uri result = null;
            if (!string.IsNullOrEmpty(uriString))
            {
                Uri.TryCreate(uriString, uriKind, out result);
            }

            return result;
        }

        /// <summary>
        /// Tries the parse date.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info.</param>
        /// <param name="dateString">The date string.</param>
        /// <param name="date">The date.</param>
        /// <returns>true if date is valid</returns>
        public static bool TryParseDate(this TimeZoneInfo timeZoneInfo, string dateString, out DateTime date)
        {
            DateTime time;
            if (!string.IsNullOrWhiteSpace(dateString) && DateTime.TryParse(dateString, null, DateTimeStyles.AssumeLocal | DateTimeStyles.AllowWhiteSpaces, out time))
            {
                time = DateTime.SpecifyKind(time, DateTimeKind.Unspecified);
                date = TimeZoneInfo.ConvertTime(time, timeZoneInfo, TimeZoneInfo.Local);
                return true;
            }

            date = DateTime.MinValue;
            return false;
        }
    }
}
